#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <assert.h>

struct test {
    int num1;
    int num2;
};

// 其他线程相关函数：
//     int pthread_cancel(pthread_t tid);  // 指定杀死一个线程，该线程会在该函数触发情况下执行一个系统调用后关闭
//     int pthread_equal(pthread_t tid1, pthread_t tid2);  // 跨平台地比较两个线程是否相同

void* callback(void *arg) {
    for (int i = 0; i < 5; ++i) {
        printf("child: i = %d\n", i);
    }
    printf("child id: %lu\n", pthread_self());
    struct test *t = (struct test*)arg;
    t->num1 = 11;
    t->num2 = 22;
    // pthread_exit(t);    // 通过退出函数返回给线程回收函数
    return t;   //  直接通过函数返回值的形式也可以
}

int main() {
    struct test t;
    pthread_t tid;
    pthread_create(&tid, NULL, callback, &t); // 第四个参数就是回调函数的参数
    for (int i = 0; i < 5; ++i) {
        printf("father: i = %d\n", i);
    }
    printf("father id: %lu\n", pthread_self());
    // sleep(3);   // 会使主线程挂起，不加这句子线程执行不到程序就结束了
    // pthread_exit(NULL); // 主线程直接退出也能使子线程开始运行
    void *ptr;

    // 通过 detach 函数分离线程可以使线程资源在线程结束后自动释放，
    // 并且主线程不需要阻塞地等待子线程 join，可以干别的
    // assert(pthread_detach(tid) == 0);

    pthread_join(tid, &ptr);    // 通过第二个参数接受子线程的传值
    printf("num1 = %d, num2 = %d\n", ((struct test*)ptr)->num1, ((struct test*)ptr)->num2);
}